package com.prj.ufdm.file.service._impl;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.mongodb.client.result.UpdateResult;
import com.prj.ufdm.file.dao.WholeFileDao;
import com.prj.ufdm.file.enums.UpFileRetCodeEnum;
import com.prj.ufdm.file.enums.WholeFileStatusEnum;
import com.prj.ufdm.file.model.AloneFile;
import com.prj.ufdm.file.model.ChunkFile;
import com.prj.ufdm.file.model.WholeFile;
import com.prj.ufdm.file.service.WholeFileService;
import com.prj.ufdm.core.exception.BaseException;

@Service
public class WholeFileServiceImpl implements WholeFileService {

	@Autowired
	private WholeFileDao wholeFileDao;
	
	/**
	 * DESC: 创建大文件上传
	 * @param wholeMd5 全文件MD5
	 * @return
	 */
	@Override
	public WholeFile createWholeFile(WholeFile wholeFile) throws Exception {
		
		System.out.println("\n createWholeFile 传入参数 wholeFile :"+wholeFile);
		
		// 设置分块总数
		validAndSetChunkCount(wholeFile);
		WholeFile existWholeFile = wholeFileDao.findWholeFileByWholeFileHash(wholeFile.getFileHash());
		
		System.out.println("\n createWholeFile 判断文件是否存在 existWholeFile:"+existWholeFile);
		// 判断文件是否存在
		if(existWholeFile!=null && existWholeFile.getId()!=null && !existWholeFile.getId().equals("") && WholeFileStatusEnum.WHILE_FILE_STATUS_1.getCode().equals(existWholeFile.getFileStatus())) {
			existWholeFile.setWholeFileId(existWholeFile.getId());
			return existWholeFile;
		}
		else {
			wholeFile.setFileStatus(WholeFileStatusEnum.WHILE_FILE_STATUS_0.getCode());
			wholeFile = wholeFileDao.insertWholeFile(wholeFile);
			if(wholeFile!=null) {
				wholeFile.setWholeFileId(wholeFile.getId());
			}
		}
		System.out.println("\n createWholeFile 创建新的 wholeFile:"+wholeFile);
		return wholeFile;
	}
	
	/**
	 * Desc: 根据wholeId查询WholeFile
	 * @param id
	 * @return
	 * @throws Exception
	 * Date: 2019年7月29日
	 * Author: Administrator
	 */
	@Override
	public WholeFile getWholeFileByWholeFileId(String wholeFileId) throws Exception {
		return wholeFileDao.findWholeFileByWholeFileId(wholeFileId);
	}
	
	/**
	 * Desc: 根据wholeId查询WholeFile
	 * @param id
	 * @return
	 * @throws Exception
	 * Date: 2019年7月29日
	 * Author: Administrator
	 */
	@Override
	public WholeFile getWholeFileByWholeFileHash(String wholeFileHash) throws Exception {
		return wholeFileDao.findWholeFileByWholeFileHash(wholeFileHash);
	}
	
	/**
	 * Desc: 更新wholeFile 
	 * @param wholeFile
	 * @return
	 * @throws Exception
	 * Date: 2019年7月29日
	 * Author: Administrator
	 */
	@Override
	public UpdateResult updateWholeFile(String wholeFileId,String chunkNum,AloneFile aloneFile) throws Exception {
		WholeFile wholeFile = wholeFileDao.findWholeFileByWholeFileId(wholeFileId);
		// 块是否存在标识
		boolean chunkNumExist = false;
		if(wholeFile!=null) {
			if(chunkNum==null || chunkNum.equals("")) {
				throw new BaseException(UpFileRetCodeEnum.RET_CODE_0401013.getCode(),UpFileRetCodeEnum.RET_CODE_0401013.getMessage());
			}
			List<ChunkFile> listChunkFile = wholeFile.getListChunkFile();
			if(listChunkFile==null) {
				listChunkFile = new ArrayList<ChunkFile>();
			}
			// 判断chunkNum是否存在
			for(ChunkFile chunkFile : listChunkFile) {
				// 判断块是否存在
				if(chunkNum.equals(chunkFile.getChunkNum())) {
					chunkNumExist = true;
					break;
				}
			}
			// 块不存在，保存块文件信息
			if(!chunkNumExist)
			{
				ChunkFile chunkFile = new ChunkFile();
				chunkFile.setFileId(aloneFile.getFileId());
				chunkFile.setChunkSize(aloneFile.getFileSize());
				chunkFile.setChunkNum(chunkNum);
				listChunkFile.add(chunkFile);
				// 设置块文件信息
				wholeFile.setListChunkFile(listChunkFile);
				// 判断分块总数与上传文件数是否相同
				if(wholeFile.getChunkCount().equals(String.valueOf(listChunkFile.size()))) {
					/**
					 * TODO: hash 校验
					 */
					wholeFile.setFileStatus(WholeFileStatusEnum.WHILE_FILE_STATUS_1.getCode());
				}
				return wholeFileDao.updateWholeFile(wholeFile);
			}
		}
		else {
			throw new BaseException(UpFileRetCodeEnum.RET_CODE_0401012.getCode(),UpFileRetCodeEnum.RET_CODE_0401012.getMessage());
		}
		return null;
	}
	
	
	/**
	 * Desc: 设置分块总数 chunkCount 
	 * @param wholeFile
	 * Date: 2019年7月29日
	 * Author: Administrator
	 */
	public void validAndSetChunkCount(WholeFile wholeFile) {
		if(wholeFile.getFileName()==null || wholeFile.getFileName().equals("")) {
			throw new BaseException(UpFileRetCodeEnum.RET_CODE_0401007.getCode(),UpFileRetCodeEnum.RET_CODE_0401007.getMessage());
		}
		if(wholeFile.getFileType()==null || wholeFile.getFileType().equals("")) {
			throw new BaseException(UpFileRetCodeEnum.RET_CODE_0401008.getCode(),UpFileRetCodeEnum.RET_CODE_0401008.getMessage());
		}
		if(wholeFile.getFileHash()==null || wholeFile.getFileHash().equals("")) {
			throw new BaseException(UpFileRetCodeEnum.RET_CODE_0401009.getCode(),UpFileRetCodeEnum.RET_CODE_0401009.getMessage());
		}
		if(wholeFile.getFileSize()==null || wholeFile.getFileSize().equals("")) {
			throw new BaseException(UpFileRetCodeEnum.RET_CODE_0401010.getCode(),UpFileRetCodeEnum.RET_CODE_0401010.getMessage());
		}
		if(wholeFile.getChunkSize()==null || wholeFile.getChunkSize().equals("")) {
			throw new BaseException(UpFileRetCodeEnum.RET_CODE_0401014.getCode(),UpFileRetCodeEnum.RET_CODE_0401014.getMessage());
		}
		
		MathContext mc = new MathContext(10, RoundingMode.HALF_UP);
		BigDecimal bigFileSize = new BigDecimal(wholeFile.getFileSize());
		BigDecimal bigChunkSize = new BigDecimal(wholeFile.getChunkSize());
		int chunkCount = (int) Math.ceil(bigFileSize.divide(bigChunkSize, mc).doubleValue()) ;
		wholeFile.setChunkCount(String.valueOf(chunkCount));
		if(wholeFile.getAliases()==null || wholeFile.getAliases().equals("")) {
			wholeFile.setAliases(wholeFile.getFileName());
		}
	}


	
}